package xyz.scootaloo.oj;

import org.junit.Test;
import xyz.scootaloo.console.app.ApplicationRunner;
import xyz.scootaloo.console.app.anno.Boot;
import xyz.scootaloo.console.app.anno.Cmd;
import xyz.scootaloo.console.app.anno.Opt;
import xyz.scootaloo.util.Cache;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
 * 统计刷题数据
 *
 * @author flutterdash@qq.com
 * @since 2021/3/24 12:00
 */
@Boot(name = "statistics")
public class Statistics {

    /**
     * launch
     * @param args ignore
     */
    public static void main(String[] args) {
        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
        ApplicationRunner.consoleApplication().run();
    }

    // 全局缓存
    private final Cache cache = new Cache();

    @Test
    public void testFunc() {
        String pack = "leetcode";
    }

    @Cmd(name = "pks")
    private List<File> packs(@Opt(value = 'p', dftVal = "true") boolean print) {
        File folder = getCurrentClassFolder();
        return Arrays.stream(Optional.ofNullable(folder.listFiles()).orElse(new File[]{}))
                .filter(File::isDirectory)
                .peek(dir -> { if (print) System.out.println(dir.getName()); })
                .collect(Collectors.toList());
    }

    @Cmd(parser = "sub")
    private void run(@Opt(value = 'p', fullName = "pack", dftVal = "leetcode") String pack,
                     @Opt(value = 'r', fullName = "refresh", dftVal = "false") boolean refresh) {
        Optional<File> packDirOpt = packs(false).stream()
                .filter(dir -> dir.getName().equals(pack))
                .findAny();
        if (packDirOpt.isEmpty())
            return;
        File packDir = packDirOpt.get();
        File sourceDir = getSourceCodeFolder(packDir);
        for (File sourcecodeFile : Optional.ofNullable(sourceDir.listFiles()).orElse(new File[] {} )) {
            if (sourcecodeFile.isDirectory()) // 排除目录
                continue;

            System.out.println(sourcecodeFile.getAbsolutePath());
        }
    }

    // 拿到源文件的头部
    private List<String> readSourceCodeFileHeader(String filename, boolean refresh) {
        String key = "source-code:" + filename;
        if (refresh) {
            List<String> codes = readSourceCodeFileHeader(filename);
            extractHeader(filename, codes);
            return cache.put(key, codes);
        } else {
            return cache.getCacheOrElse(key, () -> readSourceCodeFileHeader(filename));
        }
    }

    // 提取源文件的头部
    private void extractHeader(String filename, List<String> header) {
        String codename = filename.substring(filename.lastIndexOf(File.separator) + 1);
        codename = codename.substring(0, codename.indexOf('.'));

    }

    //
    private List<String> readSourceCodeFileHeader(String filename) {
        List<String> header = new ArrayList<>();
        try (BufferedReader reader = new BufferedReader(
                new InputStreamReader(new FileInputStream(filename), StandardCharsets.UTF_8))) {
            String currentLine;
            while ((currentLine = reader.readLine()) != null) {
                if (currentLine.isBlank())
                    continue;
                if (currentLine.startsWith("import"))
                    continue;
                if (currentLine.startsWith("@"))
                    continue;
                if (currentLine.contains("public") && currentLine.contains("class"))
                    break;
                header.add(currentLine);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return header;
    }

    private File getSourceCodeFolder(File binaryFileDirFile) {
        String binDirPath = binaryFileDirFile.getAbsolutePath();
        String targetSign = "target" + File.separator + "classes";
        String sourceSign = "src" + File.separator + "main" + File.separator + "java";
        String sourceCodePath = binDirPath.replace(targetSign, sourceSign);
        File sourceDir = new File(sourceCodePath);
        if (!sourceDir.exists())
            throw new RuntimeException("未找到源代码路径");
        return sourceDir;
    }

    private File getCurrentClassFolder() {
        final String key = "current-class-folder";
        return cache.getCacheOrElse(key, () -> new File(getCurrentClass().getResource("").getPath()));
    }

    private Class<?> getCurrentClass() {
        return Statistics.class;
    }







    private static class Problem {
        private int num;
        private final Set<String> tags;
        public Problem() {
            tags = new HashSet<>();
        }
        public void addTag(String tag) {
            tags.add(tag);
        }
        public boolean hasTag(String tag) {
            return tags.contains(tag);
        }
    }

}
